{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using a constraints file "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One of the advantages of using integer programming (or indeed any sort of constraint programming) for machine learning is that it is relatively easy to add user constraints to ensure that what is learned is consistent with known information. There are a number of ways of doing this with PyGobnilp. In this notebook we show how to declare constraints by putting them in a file. This method is particularly useful when running Gobnilp as a script from the command line, but here we will demonstrate how it works using an interactive session.\n",
    "\n",
    "We will first of all do some 'vanilla' learning where we just learn an optimal BN from some discrete data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using license file /home/james/gurobi.lic\n",
      "Academic license - for non-commercial use only\n",
      "Changed value of parameter PreCrush to 1\n",
      "   Prev: 0  Min: 0  Max: 1  Default: 0\n",
      "Changed value of parameter CutPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter GomoryPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter MIPFocus to 2\n",
      "   Prev: 0  Min: 0  Max: 3  Default: 0\n",
      "Changed value of parameter ZeroHalfCuts to 2\n",
      "   Prev: -1  Min: -1  Max: 2  Default: -1\n",
      "Changed value of parameter MIPGap to 0.0\n",
      "   Prev: 0.0001  Min: 0.0  Max: inf  Default: 0.0001\n",
      "Changed value of parameter MIPGapAbs to 0.0\n",
      "   Prev: 1e-10  Min: 0.0  Max: inf  Default: 1e-10\n",
      "**********\n",
      "BN has score -24028.0947783535\n",
      "**********\n",
      "A<- -5502.137377150637\n",
      "B<-A -3688.9395212202216\n",
      "C<- -3501.5105385969146\n",
      "D<-A,C -3555.014444236549\n",
      "E<-B,F -4310.304956470649\n",
      "F<- -3470.18794067853\n",
      "**********\n",
      "bnlearn modelstring = \n",
      "[A][B|A][C][D|A:C][E|F:B][F]\n",
      "**********\n",
      "CPDAG:\n",
      "Vertices: A,B,C,D,E,F\n",
      "A-B\n",
      "A->D\n",
      "B->E\n",
      "C->D\n",
      "F->E\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from pygobnilp.gobnilp import Gobnilp\n",
    "m = Gobnilp()\n",
    "m.learn('discrete.dat',palim=None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the learned network A and B are both ancestors of E. Suppose we wanted to learn the optimal (highest-scoring) network *subject to the condition that both A and B are not ancestors of E*. One way to do this is to put this constraint in a constraints file. A constraints file must be a Python module which defines functions effecting the constraints. For our current example, we need to provide an appropriate definition for the function `forbidden_ancestors`.\n",
    "\n",
    "Suppose we created a Python module called `cons1.py` which just contained the following definition:\n",
    "\n",
    "```\n",
    "def forbidden_ancestors(gobnilp):\n",
    "    return [('A','E'),('B','E')]\n",
    "```\n",
    "\n",
    "Then we can do this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Changed value of parameter PreCrush to 1\n",
      "   Prev: 0  Min: 0  Max: 1  Default: 0\n",
      "Changed value of parameter CutPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter GomoryPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter MIPFocus to 2\n",
      "   Prev: 0  Min: 0  Max: 3  Default: 0\n",
      "Changed value of parameter ZeroHalfCuts to 2\n",
      "   Prev: -1  Min: -1  Max: 2  Default: -1\n",
      "Changed value of parameter MIPGap to 0.0\n",
      "   Prev: 0.0001  Min: 0.0  Max: inf  Default: 0.0001\n",
      "Changed value of parameter MIPGapAbs to 0.0\n",
      "   Prev: 1e-10  Min: 0.0  Max: inf  Default: 1e-10\n",
      "**********\n",
      "BN has score -24035.844609079217\n",
      "**********\n",
      "A<-B -4349.791324894952\n",
      "B<-E,F -4134.331340440418\n",
      "E<- -5468.229676086663\n",
      "F<-E -3026.9672848237205\n",
      "C<- -3501.5105385969146\n",
      "D<-A,C -3555.014444236549\n",
      "**********\n",
      "bnlearn modelstring = \n",
      "[A|B][B|E:F][E][F|E][C][D|A:C]\n",
      "**********\n",
      "CPDAG:\n",
      "Vertices: A,B,E,F,C,D\n",
      "A->D\n",
      "B-A\n",
      "E-B\n",
      "E-F\n",
      "F-B\n",
      "C->D\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "m = Gobnilp()\n",
    "m.learn('discrete.dat',palim=None,consfile='cons1')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that this time, neither A nor B are ancestors of E. In fact E is a source node with no parents. Note also that the score of this second network is lower than the first due to these constraints.\n",
    "\n",
    "A `forbidden_ancestors` function is expected to return a list of pairs of forbidden ancestor relations (with the forbidden ancestor the first element of the pair and the forbidden descendent the second element). A user can also provide definitions for the following functions in the same way:\n",
    "\n",
    "* `forbidden_arrows`\n",
    "* `forbidden_adjacencies`\n",
    "* `obligatory_arrows`\n",
    "* `obligatory_adjacencies`\n",
    "* `obligatory_ancestors`\n",
    "* `obligatory_conditional_independences`\n",
    "\n",
    "Note that the function is called with a single argument. This will be the current `Gobnilp` object. This allows the user access, for example, to the set of BN variables. So to require that all variables are parents of, say, E, we can put the following definition in a constraints file:\n",
    "\n",
    "```\n",
    "def obligatory_arrows(gobnilp):\n",
    "    return ([(v,'E') for v in gobnilp.bn_variables if v != 'E'])\n",
    "```\n",
    "\n",
    "Suppose that definition were in a file called `cons2.py` then we can do this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Changed value of parameter PreCrush to 1\n",
      "   Prev: 0  Min: 0  Max: 1  Default: 0\n",
      "Changed value of parameter CutPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter GomoryPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter MIPFocus to 2\n",
      "   Prev: 0  Min: 0  Max: 3  Default: 0\n",
      "Changed value of parameter ZeroHalfCuts to 2\n",
      "   Prev: -1  Min: -1  Max: 2  Default: -1\n",
      "Changed value of parameter MIPGap to 0.0\n",
      "   Prev: 0.0001  Min: 0.0  Max: inf  Default: 0.0001\n",
      "Changed value of parameter MIPGapAbs to 0.0\n",
      "   Prev: 1e-10  Min: 0.0  Max: inf  Default: 1e-10\n",
      "**********\n",
      "BN has score -25116.974592860606\n",
      "**********\n",
      "A<-B -4349.791324894952\n",
      "B<- -4841.285573475907\n",
      "C<- -3501.5105385969146\n",
      "D<-A,C -3555.014444236549\n",
      "E<-A,B,C,D,F -5399.184770977754\n",
      "F<- -3470.18794067853\n",
      "**********\n",
      "bnlearn modelstring = \n",
      "[A|B][B][C][D|A:C][E|F:C:D:A:B][F]\n",
      "**********\n",
      "CPDAG:\n",
      "Vertices: A,B,C,D,E,F\n",
      "A->D\n",
      "A->E\n",
      "B-A\n",
      "B->E\n",
      "C->D\n",
      "C->E\n",
      "D->E\n",
      "F->E\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "{('A', 'E'), ('B', 'E'), ('C', 'E'), ('D', 'E'), ('F', 'E')}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Gobnilp()\n",
    "m.learn('discrete.dat',palim=None,pruning=False,consfile='cons2')\n",
    "m.obligatory_arrows"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sure enough a BN where all other nodes are parents of E is created. The BN learned is an optimal one subject to these constraints.\n",
    "\n",
    "A more complex constraint is to make certain conditional independence relations obligatory. Note that without any constraints we end up with a network where A is **not** independent of C given D. Suppose we wanted to find an optimal network subject to the constraints that A was independent of C given D. We can do this by putting the following function in a constraints file.\n",
    "\n",
    "```\n",
    "def obligatory_conditional_independences(gobnilp):\n",
    "    return [(['A'],['C'],['D'])]\n",
    "```\n",
    "\n",
    "Suppose that definition were in a file called `cons3.py`. Then we can do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Changed value of parameter PreCrush to 1\n",
      "   Prev: 0  Min: 0  Max: 1  Default: 0\n",
      "Changed value of parameter CutPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter GomoryPasses to 100000\n",
      "   Prev: -1  Min: -1  Max: 2000000000  Default: -1\n",
      "Changed value of parameter MIPFocus to 2\n",
      "   Prev: 0  Min: 0  Max: 3  Default: 0\n",
      "Changed value of parameter ZeroHalfCuts to 2\n",
      "   Prev: -1  Min: -1  Max: 2  Default: -1\n",
      "Changed value of parameter MIPGap to 0.0\n",
      "   Prev: 0.0001  Min: 0.0  Max: inf  Default: 0.0001\n",
      "Changed value of parameter MIPGapAbs to 0.0\n",
      "   Prev: 1e-10  Min: 0.0  Max: inf  Default: 1e-10\n",
      "**********\n",
      "BN has score -24832.81475418423\n",
      "**********\n",
      "A<-D -4376.2801910701055\n",
      "D<- -5496.966762872751\n",
      "B<-A -3688.9395212202216\n",
      "C<-D -3490.1353818719726\n",
      "E<-B,F -4310.304956470649\n",
      "F<- -3470.18794067853\n",
      "**********\n",
      "bnlearn modelstring = \n",
      "[A|D][D][B|A][C|D][E|F:B][F]\n",
      "**********\n",
      "CPDAG:\n",
      "Vertices: A,D,B,C,E,F\n",
      "A-B\n",
      "D-A\n",
      "D-C\n",
      "B->E\n",
      "F->E\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Forbidden arrows {('C', 'A'), ('A', 'C')}\n",
      "Forbidden adjacencies {frozenset({'A', 'C'})}\n",
      "Obligatory conditional independences {(frozenset({'A'}), frozenset({'C'}), frozenset({'D'}))}\n"
     ]
    }
   ],
   "source": [
    "m = Gobnilp()\n",
    "m.learn('discrete.dat',palim=None,pruning=False,consfile='cons3')\n",
    "print('Forbidden arrows', m.forbidden_arrows)\n",
    "print('Forbidden adjacencies', m.forbidden_adjacencies)\n",
    "print('Obligatory conditional independences', m.obligatory_conditional_independences)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this BN, A and C are indeed independent given D."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
